package com.hsy.linemoney.apiservice;

import com.deparse.dpframe.tools.utils.DPGsonUtil;
import com.hsy.linemoney.R;
import com.hsy.linemoney.requests.RequestTask;
import com.hsy.linemoney.utils.ToastUtil;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;

/**
 * 账户相关
 * Created by MartinKent on 2016/9/13.
 */
public class AccountService extends BasicService<JSONArray> {
    //    创建账户
    public void createAccountAndHolder(final JSONObject params, final Callback<JSONArray> callback, final boolean... defaultHandle) {
        String api = "/LmAccountServices-portlet.account/create-account-and-holder";
        invoke(0, api, params, new Callback<JSONArray>() {
            @Override
            public void onSuccess(int what, JSONArray result) {
                if (null != callback) {
                    callback.onSuccess(what, result);
                }
            }

            @Override
            public void onError(int what, int type, String msg, Exception e) {
                if (e instanceof RequestTask.StatusCodeException && (null == defaultHandle || 0 == defaultHandle.length || defaultHandle[0])) {
                    ToastUtil.showToast(msg);
                } else {
                    ToastUtil.showToast(R.string.txt_network_failure);
                }
                if (null != callback) {
                    callback.onError(0, 0, e.getLocalizedMessage(), e);
                }
            }
        });
    }

    //    获取账户列表
    public void getAccounts(final Callback<AccountListResult> callback, boolean... clearData) {
        if (null != clearData && clearData.length > 0 && clearData[0]) {//如果需要清除缓存
            DataHolder.mAccountListResult = null;//清除缓存
        }
        if (null != DataHolder.mAccountListResult) {//如果存在缓存数据，使用缓存数据
            if (null != callback) {
                callback.onSuccess(0, DataHolder.mAccountListResult);
            }
            return;
        }
        //如果不存在缓存数据，调用接口获取数据
        String api = "/LmAccountServices-portlet.account/get-account-with-holder";
        JSONObject params = ParamsMaker.newInstance().add("userId", LineMoneyContext.getLoggedUser().getUserId()).get();
        invoke(0, api, params, new Callback<JSONArray>() {
            @Override
            public void onSuccess(int what, JSONArray result) {
                try {
                    DataHolder.mAccountListResult = DPGsonUtil.fromJson(result.get(0).toString(), AccountListResult.class);
                    if (null != callback) {
                        callback.onSuccess(what, DataHolder.mAccountListResult);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                    callback.onError(what, 0, e.getLocalizedMessage(), e);
                }
            }

            @Override
            public void onError(int what, int type, String msg, Exception e) {
                if (e instanceof RequestTask.StatusCodeException) {
                    ToastUtil.showToast(msg);
                } else {
                    ToastUtil.showToast(R.string.txt_network_failure);
                }
                if (null != callback) {
                    callback.onError(what, 0, msg, e);
                }
            }
        });
    }

    //    检查账户密码是否正确
    public void checkAccountPassword(final String pass, final Callback<JSONObject> callback) {
        String api = "/LmAccountServices-portlet.account/check-account-password";
        JSONObject params = ParamsMaker.newInstance()
                .add("inputPassword", pass)
                .add("userId", LineMoneyContext.getLoggedUser().getUserId())
                .get();
        invoke(0, api, params, new Callback<JSONArray>() {
            @Override
            public void onSuccess(int what, JSONArray result) {
                if (null != callback) {
                    try {
                        callback.onSuccess(what, result.getJSONObject(0));
                    } catch (JSONException e) {
                        e.printStackTrace();
                        callback.onError(what, 0, e.getLocalizedMessage(), e);
                    }
                }
            }

            @Override
            public void onError(int what, int type, String msg, Exception e) {
                if (null != callback) {
                    callback.onError(what, 0, e.getLocalizedMessage(), e);
                }
            }
        });
    }

    //    获取现金流和余额报告
    public void getCashflow(String accountId, String timePeriod, final Callback<CashflowResult> callback) {
        String api = "/LmBusinessServices-portlet.transaction/user/cashflow";
        JSONObject params = ParamsMaker.newInstance()
                .add("accountId", accountId)
                .add("timePeriod", timePeriod)
                .add("userId", LineMoneyContext.getLoggedUser().getUserId())
                .get();
        invoke(0, api, params, new Callback<JSONArray>() {
            @Override
            public void onSuccess(int what, JSONArray result) {
                try {
                    if (null != callback) {
                        callback.onSuccess(what, DPGsonUtil.fromJson(result.get(0).toString(), CashflowResult.class));
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                    callback.onError(what, 0, e.getLocalizedMessage(), e);
                }
            }

            @Override
            public void onError(int what, int type, String msg, Exception e) {
                if (e instanceof RequestTask.StatusCodeException) {
                    ToastUtil.showToast(msg);
                } else {
                    ToastUtil.showToast(R.string.txt_network_failure);
                }
                if (null != callback) {
                    callback.onError(what, 0, msg, e);
                }
            }
        });
    }

    public static class AccountListResult {
        public static final int ALL = 0;
        public static final int RECEIVE = 1;
        public static final int SEND = 2;

        private Status status;

        private List<Value> value;

        private String[] all, send, receive;

        public void setStatus(Status status) {
            this.status = status;
        }

        public Status getStatus() {
            return this.status;
        }

        public void setValue(List<Value> value) {
            this.value = value;
        }

        public List<Value> getValue() {
            return this.value;
        }

        public String[] getAccountNameArray(int type) {
            if (type == ALL) {
                return getNameArray(all);
            } else if (type == SEND) {
                return getNameArray(send);
            } else if (type == RECEIVE) {
                return getNameArray(receive);
            }
            return null;
        }

        private String[] getNameArray(String[] out) {
            if (null == out || 0 == out.length) {
                out = new String[value.size()];
                int i = 0;
                for (Value item : value) {
                    out[i++] = item.getAccountName();
                }
            }
            return out;
        }

        private List<Value> allAccounts, sendAccounts, receiveAccounts;

        public List<Value> getAccountsByType(String type) {
            if ("all".equalsIgnoreCase(type)) {
                if (null == allAccounts) {
                    allAccounts = new ArrayList<>();
                    allAccounts.addAll(value);
                }
                return value;
            } else if ("send".equalsIgnoreCase(type)) {
                if (null == sendAccounts) {
                    sendAccounts = new ArrayList<>();
                    for (Value item : value) {
                        if (type.equals(item.getAccountTypeCd())) {
                            sendAccounts.add(item);
                        }
                    }
                }
                return sendAccounts;
            } else if ("receive".equalsIgnoreCase(type)) {
                if (null == receiveAccounts) {
                    receiveAccounts = new ArrayList<>();
                    for (Value item : value) {
                        if (type.equals(item.getAccountTypeCd())) {
                            receiveAccounts.add(item);
                        }
                    }
                }
                return receiveAccounts;
            }
            return null;
        }

        public static class Status {
            private String message;

            private String code;

            public void setMessage(String message) {
                this.message = message;
            }

            public String getMessage() {
                return this.message;
            }

            public void setCode(String code) {
                this.code = code;
            }

            public String getCode() {
                return this.code;
            }

        }

        public static class Value {
            private String phone;

            private String accountId;

            private String state;

            private String currencyCd;

            private String city;

            private String balance;

            private String holderCountryCd;

            private String userId;

            private String zipCode;

            private String firstName;

            private String middleName;

            private String lastName;

            private String accountTypeCd;

            private String bankCd;

            private String paymentTypeCd;

            private String addressLine3;

            private String addressLine2;

            private String addressLine1;

            private String securityCode;

            private String bestContact;

            private String accountName;

            private String holderState;

            private String email;

            private String accountHolderId;

            private String fullName;

            private String cardNumber;

            private String bankAccount;

            public void setPhone(String phone) {
                this.phone = phone;
            }

            public String getPhone() {
                return this.phone;
            }

            public void setAccountId(String accountId) {
                this.accountId = accountId;
            }

            public String getAccountId() {
                return this.accountId;
            }

            public void setState(String state) {
                this.state = state;
            }

            public String getState() {
                return this.state;
            }

            public void setCurrencyCd(String currencyCd) {
                this.currencyCd = currencyCd;
            }

            public String getCurrencyCd() {
                return this.currencyCd;
            }

            public void setCity(String city) {
                this.city = city;
            }

            public String getCity() {
                return this.city;
            }

            public void setBalance(String balance) {
                this.balance = balance;
            }

            public String getBalance() {
                return this.balance;
            }

            public void setHolderCountryCd(String holderCountryCd) {
                this.holderCountryCd = holderCountryCd;
            }

            public String getHolderCountryCd() {
                return this.holderCountryCd;
            }

            public void setUserId(String userId) {
                this.userId = userId;
            }

            public String getUserId() {
                return this.userId;
            }

            public void setZipCode(String zipCode) {
                this.zipCode = zipCode;
            }

            public String getZipCode() {
                return this.zipCode;
            }

            public void setFirstName(String firstName) {
                this.firstName = firstName;
            }

            public String getFirstName() {
                return this.firstName;
            }

            public void setMiddleName(String middleName) {
                this.middleName = middleName;
            }

            public String getMiddleName() {
                return this.middleName;
            }

            public void setLastName(String lastName) {
                this.lastName = lastName;
            }

            public String getLastName() {
                return this.lastName;
            }

            public void setAccountTypeCd(String accountTypeCd) {
                this.accountTypeCd = accountTypeCd;
            }

            public String getAccountTypeCd() {
                return this.accountTypeCd;
            }

            public void setBankCd(String bankCd) {
                this.bankCd = bankCd;
            }

            public String getBankCd() {
                return this.bankCd;
            }

            public void setPaymentTypeCd(String paymentTypeCd) {
                this.paymentTypeCd = paymentTypeCd;
            }

            public String getPaymentTypeCd() {
                return this.paymentTypeCd;
            }

            public void setAddressLine3(String addressLine3) {
                this.addressLine3 = addressLine3;
            }

            public String getAddressLine3() {
                return this.addressLine3;
            }

            public void setAddressLine2(String addressLine2) {
                this.addressLine2 = addressLine2;
            }

            public String getAddressLine2() {
                return this.addressLine2;
            }

            public void setAddressLine1(String addressLine1) {
                this.addressLine1 = addressLine1;
            }

            public String getAddressLine1() {
                return this.addressLine1;
            }

            public void setSecurityCode(String securityCode) {
                this.securityCode = securityCode;
            }

            public String getSecurityCode() {
                return this.securityCode;
            }

            public void setBestContact(String bestContact) {
                this.bestContact = bestContact;
            }

            public String getBestContact() {
                return this.bestContact;
            }

            public void setAccountName(String accountName) {
                this.accountName = accountName;
            }

            public String getAccountName() {
                return this.accountName;
            }

            public void setHolderState(String holderState) {
                this.holderState = holderState;
            }

            public String getHolderState() {
                return this.holderState;
            }

            public void setEmail(String email) {
                this.email = email;
            }

            public String getEmail() {
                return this.email;
            }

            public void setAccountHolderId(String accountHolderId) {
                this.accountHolderId = accountHolderId;
            }

            public String getAccountHolderId() {
                return this.accountHolderId;
            }

            public void setFullName(String fullName) {
                this.fullName = fullName;
            }

            public String getFullName() {
                return this.fullName;
            }

            public void setCardNumber(String cardNumber) {
                this.cardNumber = cardNumber;
            }

            public String getCardNumber() {
                return this.cardNumber;
            }

            public void setBankAccount(String bankAccount) {
                this.bankAccount = bankAccount;
            }

            public String getBankAccount() {
                return this.bankAccount;
            }

        }
    }

    //    获取可提现账户列表
    public void getCashableAccounts(final Callback<CashableAccountsResult> callback, boolean... clearData) {
        if (null != clearData && clearData.length > 0 && clearData[0]) {
            DataHolder.mCashableAccountsResult = null;
        }
        if (null != DataHolder.mCashableAccountsResult) {
            if (null != callback) {
                callback.onSuccess(0, DataHolder.mCashableAccountsResult);
            }
            return;
        }
        String api = "/LmAgentPoint-portlet.userpointtotal/get-user-cash-account";
        JSONObject params = ParamsMaker.newInstance().add("userId", LineMoneyContext.getLoggedUser().getUserId()).get();
        invoke(0, api, params, new Callback<JSONArray>() {
            @Override
            public void onSuccess(int what, JSONArray result) {
                try {
                    DataHolder.mCashableAccountsResult = DPGsonUtil.fromJson(result.get(0).toString(), CashableAccountsResult.class);
                    if (null != callback) {
                        callback.onSuccess(what, DataHolder.mCashableAccountsResult);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                    callback.onError(what, 0, e.getLocalizedMessage(), e);
                }
            }

            @Override
            public void onError(int what, int type, String msg, Exception e) {
                if (e instanceof RequestTask.StatusCodeException) {
                    ToastUtil.showToast(msg);
                } else {
                    ToastUtil.showToast(R.string.txt_network_failure);
                }
                if (null != callback) {
                    callback.onError(what, 0, msg, e);
                }
            }
        });
    }

    public static class CashableAccountsResult {

        private String[] names;

        private Status status;

        private Value value;

        public void setStatus(Status status) {
            this.status = status;
        }

        public Status getStatus() {
            return this.status;
        }

        public void setValue(Value value) {
            this.value = value;
        }

        public Value getValue() {
            return this.value;
        }

        public String[] getAccountNameArray() {
            if (null == names || 0 == names.length) {
                names = new String[value.getAccounts().size()];
                int i = 0;
                for (CashableAccountsResult.Accounts item : value.getAccounts()) {
                    names[i++] = item.getAccount_name();
                }
            }
            return names;
        }

        public class Value {
            private List<Accounts> accounts;

            private String userId;

            public void setAccounts(List<Accounts> accounts) {
                this.accounts = accounts;
            }

            public List<Accounts> getAccounts() {
                return this.accounts;
            }

            public void setUserId(String userId) {
                this.userId = userId;
            }

            public String getUserId() {
                return this.userId;
            }

        }

        public class Accounts {
            private String account_id;

            private String account_name;

            public void setAccount_id(String account_id) {
                this.account_id = account_id;
            }

            public String getAccount_id() {
                return this.account_id;
            }

            public void setAccount_name(String account_name) {
                this.account_name = account_name;
            }

            public String getAccount_name() {
                return this.account_name;
            }

        }

        public class Status {
            private String message;

            private String code;

            public void setMessage(String message) {
                this.message = message;
            }

            public String getMessage() {
                return this.message;
            }

            public void setCode(String code) {
                this.code = code;
            }

            public String getCode() {
                return this.code;
            }

        }
    }

    //    获取现金流和余额报告删选条件
    public void getCashAndReportFilter(final Callback<CashAndReportFilterResult> callback, boolean... clearData) {
        if (null != clearData && clearData.length > 0 && clearData[0]) {
            DataHolder.mCashAndReportFilterResult = null;
        }
        if (null != DataHolder.mCashAndReportFilterResult) {
            if (null != callback) {
                callback.onSuccess(0, DataHolder.mCashAndReportFilterResult);
            }
            return;
        }
        String api = "/LmAccountServices-portlet.account/user/accountsByType";
        JSONObject params = ParamsMaker.newInstance()
                .add("userId", LineMoneyContext.getLoggedUser().getUserId())
                .add("accountType", "SEND")
                .get();
        invoke(0, api, params, new Callback<JSONArray>() {
            @Override
            public void onSuccess(int what, JSONArray result) {
                try {
                    DataHolder.mCashAndReportFilterResult = DPGsonUtil.fromJson(result.get(0).toString(), CashAndReportFilterResult.class);
                    if (null != callback) {
                        callback.onSuccess(what, DataHolder.mCashAndReportFilterResult);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                    callback.onError(what, 0, e.getLocalizedMessage(), e);
                }
            }

            @Override
            public void onError(int what, int type, String msg, Exception e) {
                if (e instanceof RequestTask.StatusCodeException) {
                    ToastUtil.showToast(msg);
                } else {
                    ToastUtil.showToast(R.string.txt_network_failure);
                }
                if (null != callback) {
                    callback.onError(what, 0, msg, e);
                }
            }
        });
    }

    public static class CashAndReportFilterResult {
        private Status status;

        private Data data;

        public void setStatus(Status status) {
            this.status = status;
        }

        public Status getStatus() {
            return this.status;
        }

        public void setData(Data data) {
            this.data = data;
        }

        public Data getData() {
            return this.data;
        }

        public class Data {
            private List<ReportPeriods> reportPeriods;

            private String[] accounts;

            public void setReportPeriods(List<ReportPeriods> reportPeriods) {
                this.reportPeriods = reportPeriods;
            }

            public List<ReportPeriods> getReportPeriods() {
                return this.reportPeriods;
            }

            public void setAccounts(String[] accounts) {
                this.accounts = accounts;
            }

            public String[] getAccounts() {
                return this.accounts;
            }

            private String[] periodNames;

            public String[] getReportPeriodNames() {
                if (null == periodNames) {
                    periodNames = new String[reportPeriods.size()];
                    int i = 0;
                    for (ReportPeriods item : reportPeriods) {
                        periodNames[i++] = item.getLabel();
                    }
                }
                return periodNames;
            }
        }

        public class ReportPeriods {
            private String value;

            private String label;

            public void setValue(String value) {
                this.value = value;
            }

            public String getValue() {
                return this.value;
            }

            public void setLabel(String label) {
                this.label = label;
            }

            public String getLabel() {
                return this.label;
            }

        }

        public class Status {
            private int statusCode;

            public void setStatusCode(int statusCode) {
                this.statusCode = statusCode;
            }

            public int getStatusCode() {
                return this.statusCode;
            }

        }
    }

    public static class CashflowResult {
        private Status status;

        private Data data;

        public void setStatus(Status status) {
            this.status = status;
        }

        public Status getStatus() {
            return this.status;
        }

        public void setData(Data data) {
            this.data = data;
        }

        public Data getData() {
            return this.data;
        }

        public class Data {
            private List<Transactions> transactions;

            public void setTransactions(List<Transactions> transactions) {
                this.transactions = transactions;
            }

            public List<Transactions> getTransactions() {
                return this.transactions;
            }

        }

        public class Transactions {
            private String balance;

            private String description;

            private String debit;

            private String serviceTypeCd;

            private String transactionDate;

            public void setBalance(String balance) {
                this.balance = balance;
            }

            public String getBalance() {
                return this.balance;
            }

            public void setDescription(String description) {
                this.description = description;
            }

            public String getDescription() {
                return this.description;
            }

            public void setDebit(String debit) {
                this.debit = debit;
            }

            public String getDebit() {
                return this.debit;
            }

            public void setServiceTypeCd(String serviceTypeCd) {
                this.serviceTypeCd = serviceTypeCd;
            }

            public String getServiceTypeCd() {
                return this.serviceTypeCd;
            }

            public void setTransactionDate(String transactionDate) {
                this.transactionDate = transactionDate;
            }

            public String getTransactionDate() {
                return this.transactionDate;
            }

        }

        public class Status {
            private String statusCode;

            public void setStatusCode(String statusCode) {
                this.statusCode = statusCode;
            }

            public String getStatusCode() {
                return this.statusCode;
            }

        }
    }
}
